﻿//===============================================================================
// Magic OQL
//===============================================================================
// Copyright ?Magic Thought Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// Richie (http://www.cnblogs.com/RicCC)
// March 7, 2008
//===============================================================================

using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace SQLAnalyticLibrary.Expressions
{
    /// <summary>
    /// Union statement:
    /// <para>SelectStatement (UnionOperator SelectStatement)* OrderByClause?</para>
    /// </summary>
    public class UnionStatement : QueryStatement
    {
        #region constructors
        /// <summary>
        /// UnionStmt is a imaginary token. Don't need combine subsequent tokens.
        /// </summary>
        /// <param name="node"></param>
        public UnionStatement(IToken t, string text)
            : base(t, text)
        {
        }
        /// <summary>
        /// UnionStmt is a imaginary token. Don't need combine subsequent tokens.
        /// </summary>
        /// <param name="node"></param>
        public UnionStatement(IToken t)
            : base(t)
        {
        }
        #endregion

        public override Expression DupNode()
        {
            return new UnionStatement(this.Token);
        }
        protected override void PostVisitCompile()
        {
            for (int i = 0; this._children != null && i < this._children.Count; i++)
                if (i % 2 == 0 && SelectStatement.IsSelectStatement(this._children[i]))
                    (this._children[i] as SelectStatement).NeedParen = false;
        }

        public override bool IsTableAlias(string table, bool subQuery)
        {
            //in union statement, only those table & column references from order by clause will trigger this method call.
            //Currently the following syntax comes from SQL Server 2005, only the alias in the first select statement is valid in order by clause.
            if (this._children == null || this._children.Count <= 0) return false;
            SelectStatement selectStatement = this._children[0] as SelectStatement;
            if (selectStatement == null) return false;
            return selectStatement.IsTableAlias(table, subQuery);
        }
        public override bool IsColumnAlias(string column, bool subQuery)
        {
            //Currently the following syntax comes from SQL Server 2005
            //Currently the following syntax comes from SQL Server 2005, only the alias in the first select statement is valid in order by clause.
            if (this._children == null || this._children.Count <= 0) return false;
            SelectStatement selectStatement = this._children[0] as SelectStatement;
            if (selectStatement == null) return false;
            return selectStatement.IsColumnAlias(column, subQuery);
        }
        public static bool IsUnionStatement(Expression exp)
        {
            if (exp == null || exp.IsNil) return false;
            return exp.Token.Type == OQLParser.UnionStmt;
        }
    }
}
